package com.ttmusic.utils;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

import com.ttmusic.activitys.R;
import com.ttmusic.application.TTApplication;
import com.ttmusic.dao.AlbumInfoDao;
import com.ttmusic.dao.ArtistInfoDao;
import com.ttmusic.dao.MusicInfoDao;
import com.ttmusic.entity.AbstractMusic;
import com.ttmusic.entity.AlbumInfo;
import com.ttmusic.entity.ArtistInfo;
import com.ttmusic.entity.MusicInfo;
import com.ttmusic.utils.SQLite.SQLiteUtil;
import com.ttmusic.utils.baidu.Song;
import com.ttmusic.utils.baidu.SongInfoDownload;
import com.ttmusic.view.listeners.OnScanListener;

/**
 * 音乐查询工具类
 * @author wuchangyong
 *
 */
public class MusicUtils {
	
	public MusicUtils(Context context) {
        this.mContext = context;
        musicDao = MusicInfoDao.getInstance();
        artistDao = ArtistInfoDao.getInstance();
        albumDao = AlbumInfoDao.getInstance();
    }
	
	private MusicInfoDao musicDao;
	private ArtistInfoDao artistDao;
	private AlbumInfoDao albumDao;
	
    public static final String TAG = "MusicUtils";
    
    public static final String ARTIST_ALBUM_IMAGE_PATH = Environment.getExternalStorageDirectory().toString()
    		+ "/TTmusic/ARTIST_ALBUM_IMAGE/";
    

    public static final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
    private static final BitmapFactory.Options sBitmapOptionsCache = new BitmapFactory.Options();
//	private static final BitmapFactory.Options sBitmapOptions = new BitmapFactory.Options();

    //查询歌曲时用到的列名称数组
    private static String[] proj_music = {
            MediaStore.Audio.Media._ID, 
            MediaStore.Audio.Media.TITLE,
            MediaStore.Audio.Media.DATA, 
            MediaStore.Audio.Media.ALBUM_ID,
            MediaStore.Audio.Media.ARTIST, 
            MediaStore.Audio.Media.ARTIST_ID,
            MediaStore.Audio.Media.DURATION};
    //查询专辑时用到的列名称
    private static String[] proj_album = {
    		MediaStore.Audio.Albums.ALBUM,
            MediaStore.Audio.Albums.NUMBER_OF_SONGS, 
            MediaStore.Audio.Albums._ID, 
            MediaStore.Audio.Albums.ALBUM_ART, 
            MediaStore.Audio.Albums.ARTIST};
    //查询艺术家时用到列名称
    private static String[] proj_artist = new String[]{
            MediaStore.Audio.Artists._ID,
            MediaStore.Audio.Artists.ARTIST,
            MediaStore.Audio.Artists.NUMBER_OF_ALBUMS};

	private static String[] proj_art_to_album = { MediaStore.Audio.Artists.Albums.ALBUM_ART};

    public static final int THUMBNAIL_LEN_DP = 56;

    public static final int MSG_SCAN_SUCCESS = 0;   //所有音乐扫描成功
    public static final int MSG_SCAM_FAIL = 1;  //扫描失败 或者取消
    public static final int MSG_SCAN_ING = 2;   //正在扫描某首歌  一般是扫描完成后显示

    public static final String KEY_BUNDLE_MUSICINFO = "KEY_BUNDLE_MUSICINFO";

    private Context mContext;

    private OnScanListener mOnScanListener;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (mOnScanListener != null) {
                switch (msg.what) {
                    case MSG_SCAN_SUCCESS:
                        mOnScanListener.onSuccess();
                        break;
                    case MSG_SCAM_FAIL:
                        mOnScanListener.onFail();
                        break;
                    case MSG_SCAN_ING:
                        mOnScanListener.onScan((MusicInfo) msg.getData().getParcelable(KEY_BUNDLE_MUSICINFO));
                        break;
                }
            }
        }
    };


    /**
     * 开始扫描
     */
    public void startScan() {
    	new Thread(new Runnable() {
    		@Override
            public void run() {
                scanMusicToSQLite();
            }
		}).start();
    }

    public void setOnScanListener(OnScanListener mOnScanListener) {
        this.mOnScanListener = mOnScanListener;
    }

    /**
     * 扫描本地音乐  并且添加到本地数据库
     */
    private boolean scanMusicToSQLite() {
    	//先清空歌曲表、专辑表和歌手表的数据
//    	SQLiteUtil.deleteAllData("TB_MUSIC_INFO");
//    	SQLiteUtil.deleteAllData("TB_ALBUM_INFO");
//    	SQLiteUtil.deleteAllData("TB_ARTIST_INFO");
//    	this.clearLocalPNG();
    	
    	List<MusicInfo> mis = this.findLocalMusic();
    	final Random random = new Random();
    	for(int i=0;i<mis.size();i++) {
    		try {
				Thread.sleep(new Random().nextInt(100) + 50);
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
    		final MusicInfo mi = mis.get(i);
    		//System.out.println("歌曲："+mi.getSongId() + " (歌手：" + mi.getArtistId() + " " + mi.getArtist() + ") (专辑：" + mi.getAlbumId() + " " + mi.getAlbum() + ")");
    		
            try {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                    	if (mi == null) {
                            return;
                        }
                        //从数据库里查询 存在就跳过 不存在就新增
                        AbstractMusic musicInfo = musicDao.loadByName(mi.getTitle());
                        if(null == musicInfo) {
                        	//从手机里查询
                        	AlbumInfo album = getAlbumById(mi.getAlbumId());
                        	long artistId = -1;
                        	String savePath = null;
                        	//从数据库里加载歌手 判断该歌手若存在 就将歌手歌曲数量+1  不存在就新增歌手
                        	ArtistInfo artistInfo = artistDao.loadByName(mi.getArtist());
                            if (artistInfo == null) {
                            	ArtistInfo art = new ArtistInfo(mi.getArtist(), 1, null);
                            	if(null != album && null != album.getAlbumArt() && !"".equals(album.getAlbumArt())) {
                            		savePath = ARTIST_ALBUM_IMAGE_PATH + random.nextInt(10000) + System.currentTimeMillis()  + ".png";
                            		writeBitMapToLocalPNG(album, savePath);
                            		art.setAlbumArt(savePath);
                            	}
                            	artistId = artistDao.save(art);
                            }else {
                            	artistId = artistInfo.getArtistId();
                            	artistInfo.setNumSongs(artistInfo.getNumSongs() + 1);
                            	artistDao.update(artistInfo);
                            }
                            long albumId = -1;
                            //从数据库里面查询专辑 判断专辑若存在 就将专辑歌曲数量+1 不存在就新增专辑
                            AlbumInfo albumInfo = albumDao.loadByName(mi.getAlbum().trim());
                            if (albumInfo == null) {
                            	albumInfo = new AlbumInfo(mi.getAlbum(), mi.getArtist(), 1, null);
                            	if(null != savePath && !"".equals(savePath)) {
                            		albumInfo.setAlbumArt(album.getAlbumArt());
                            	}
                            	albumId = albumDao.save(albumInfo);
                            }else {
                            	albumInfo.setNumSongs(albumInfo.getNumSongs() + 1);
                            	albumDao.update(albumInfo);
                            	albumId = albumInfo.getAlbumId();
                            }
                        	mi.setArtistId(artistId);
                        	mi.setAlbumId(albumId);
                        	musicDao.save(mi);
                        }
                    }
                }).start();

                Message msg = Message.obtain();
                msg.what = MSG_SCAN_ING;
                Bundle bundle = new Bundle();
                bundle.putParcelable(KEY_BUNDLE_MUSICINFO, mi);
                msg.setData(bundle);
                mHandler.sendMessage(msg);
            } catch (Exception e) {
                Log.i(TAG, "Exception:" + e.toString());
                e.printStackTrace();
                mHandler.sendEmptyMessage(MSG_SCAM_FAIL);
                return false;
            }
        }
        mHandler.sendEmptyMessage(MSG_SCAN_SUCCESS);
        return true;
    }
    
    public void clearLocalPNG() {
    	File f = new File(ARTIST_ALBUM_IMAGE_PATH);
    	if(f.exists() && f.isDirectory()) {
    		for(File img : f.listFiles()) {
    			img.delete();
    		}
    	}
    }
    
    /**
     * 将专辑或艺术家的图片写入本地SDK中
     * @param album
     * @param savePath
     */
    public void writeBitMapToLocalPNG(AlbumInfo album, String savePath) {
    	ByteArrayOutputStream baos = null;
    	FileOutputStream out = null;
    	try {
	    	Bitmap bm = getArtworkQuick(mContext, album.getAlbumId());
	    	baos = new ByteArrayOutputStream();
			bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
			File f = new File(ARTIST_ALBUM_IMAGE_PATH);
			if(!f.exists()) {
				f.mkdirs();
			}
			out = new FileOutputStream(savePath);
			out.write(baos.toByteArray());
			out.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(null != out) out.close();
				if(null != baos) baos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
    }

    /**
     * 通过Id查询专辑信息   contentProvider
     *
     * @param albumId
     * @return
     */
    private AlbumInfo getAlbumById(Long albumId) {
        ContentResolver cr = mContext.getContentResolver();
        AlbumInfo albumInfo = new AlbumInfo();
        String selection = MediaStore.Audio.Albums._ID + " =? ";
        String[] selectionArgs = new String[]{albumId + ""};
        Cursor cursor = cr.query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, proj_album,
                selection, selectionArgs,
                MediaStore.Audio.Albums.DEFAULT_SORT_ORDER);
        if (cursor != null && cursor.moveToNext()) {
            albumInfo.setAlbumId(cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Albums._ID)));
            albumInfo.setAlbumArt(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART)));
            albumInfo.setArtist(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Albums.ARTIST)));
            albumInfo.setNumSongs(cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Albums.NUMBER_OF_SONGS)));
            albumInfo.setTitle(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM)));
            return albumInfo;
        }
        return null;
    }

//    /**
//     * 从手机通过artistId查询艺术家 保存到自己创建的表中
//     * @return List<ArtistInfo>
//     */
//    public List<ArtistInfo> getArtistInfos() {
//        ContentResolver cr = mContext.getContentResolver();
////        String selection = MediaStore.Audio.Artists._ID + " =? ";
////        String[] selectionArgs = new String[]{artistId + ""};
//        Cursor cursor = cr.query(MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI, proj_artist,
//                null, null, MediaStore.Audio.Artists.DEFAULT_SORT_ORDER);
//        List<ArtistInfo> arts = new ArrayList<ArtistInfo>();
//        if (cursor != null) {
//        	while(cursor.moveToNext()) {
//        		ArtistInfo artistInfo = new ArtistInfo();
//        		artistInfo.setArtistId(cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Artists._ID)));
//        		artistInfo.setArtist(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Artists.ARTIST)));
//        		artistInfo.setNumSongs(cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Artists.NUMBER_OF_ALBUMS)));
//        		arts.add(artistInfo);
//        	}
//        }
//        return arts;
//    }
    
    /**
	 * 查找本机音乐文件
	 * @param contentResolver
	 * @return
	 */
	private List<MusicInfo> findLocalMusic(){
		List<MusicInfo> musicInfos = new ArrayList<MusicInfo>();
		StringBuffer select = new StringBuffer(" 1=1 ");
        // 拼接查询语句的where条件：检索出 时长大于1分钟，文件大小大于1MB的媒体文件
//        if (SharedPreferencesUtil.isFilterSize(mContext)) {
//            select.append(" and " + MediaStore.Audio.Media.SIZE + " > " + IContain.FILTER_SIZE);
//        }
        if (SharedPreferencesUtil.isFilterDuration(mContext)) {
            select.append(" and " + MediaStore.Audio.Media.DURATION + " > " + IContain.FILTER_DURATION);
        }
		/*
		 * ContentResolver对象是专门访问android手机内置的数据库，提供了以下4个方法实现了增删改查功能
		 * 返回值	函数声明
		 * Uri insert(Uri url, ContentValues values)
		 * 		Inserts a row into a table at the given URL.
		 * int delete(Uri url, String where, String[] selectionArgs)
		 * 		Deletes row(s) specified by a content URI.
		 * Cursor query (Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
		 * 		Query the given URI, returning a Cursor over the result set.
		 * int update (Uri uri, ContentValues values, String where, String[] selectionArgs)
		 * 		Update row(s) in a content URI.
		 */
		Cursor cursor = mContext.getContentResolver().query(  
                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, select.toString(), null,  
                MediaStore.Audio.Media.TITLE); 
		MusicInfo musicInfo = null;
		for (int i = 0; i < cursor.getCount(); i++) { 
			//游标指针向下移动一位
			cursor.moveToNext(); 
			//是否为音乐
            int isMusic = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC));  
            if(isMusic != 0) {
				//新建一个歌曲对象,将从cursor里读出的信息存放进去,直到取完cursor里面的内容为止.  
				musicInfo = new MusicInfo();                               
				//音乐id  
	            long id = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media._ID));   
	            //音乐标题
	            String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
	            //艺术家ID
	            long artistId = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST_ID));
	            //艺术家
	            String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));  
	            //时长
	            int duration = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION));  
	            //文件大小
	            //long size = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.SIZE));    
	            //文件路径
	            String path = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));    
	            //唱片专辑
	            String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));   
	            //唱片专辑ID
	            long album_id = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));   
	            //添加时间
	            long addTime = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DATE_ADDED));
	            
	            //只把2分钟以上的音乐添加到集合当中  
	            //if (isMusic != 0 && duration/(1000 * 120) >= 1) {   
		            musicInfo.setSongId(id);
		            musicInfo.setAlbumId(album_id);
		            musicInfo.setArtistId(artistId);
		            musicInfo.setTitle(title);
		            musicInfo.setAlbum(album);
		            musicInfo.setArtist(artist);
		            musicInfo.setDuration(duration);
		            musicInfo.setPath(path);
		            musicInfo.setAddTime(addTime);
		            musicInfo.setFavorite(0);  
		            musicInfos.add(musicInfo);
	            //}
            }
        }  
//		System.out.println("共找到了 " + musicInfos.size() + " 首歌曲。。。");
		return musicInfos;
	}


    /**
     * 默认是缩略图
     *
     * @param context
     * @param album_id
     * @return
     */
    public static Bitmap getArtworkQuick(Context context, long album_id) {
        //BitmapDrawable bd = (BitmapDrawable) context.getResources().getDrawable(R.drawable.img_album_background);
        int thumbnailLen_px = DisplayUtil.dip2px(context, THUMBNAIL_LEN_DP);
        return getArtworkQuick(context, album_id, thumbnailLen_px, thumbnailLen_px);  //默认尺寸
    }

    //todo 添加其他两种类型的size
    public static Bitmap getArtworkQuick(Context context, long album_id, AbstractMusic.PicSizeType picSizeType) {
        switch (picSizeType) {
            case SMALL:
                return getArtworkQuick(context, album_id);
            case HUGE:
                return getArtworkQuick(context, album_id, TTApplication.mScreenWidth, TTApplication.mScreenHeight);
        }
        return null;
    }

    public static Bitmap getArtworkQuick(Context context, long album_id, int w, int h) {
        w -= 1;
        ContentResolver res = context.getContentResolver();
        Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id);
        if (uri != null) {
            ParcelFileDescriptor fd = null;
            try {
                fd = res.openFileDescriptor(uri, "r");
                int sampleSize = 1;

                sBitmapOptionsCache.inJustDecodeBounds = true;
                BitmapFactory.decodeFileDescriptor(fd.getFileDescriptor(), null, sBitmapOptionsCache);
                int nextWidth = sBitmapOptionsCache.outWidth >> 1;
                int nextHeight = sBitmapOptionsCache.outHeight >> 1;
                while (nextWidth > w && nextHeight > h) {
                    sampleSize <<= 1;
                    nextWidth >>= 1;
                    nextHeight >>= 1;
                }

                sBitmapOptionsCache.inSampleSize = sampleSize;
                sBitmapOptionsCache.inJustDecodeBounds = false;
                Bitmap b = BitmapFactory.decodeFileDescriptor(fd.getFileDescriptor(), null, sBitmapOptionsCache);

                if (b != null) {
                    //按照所给的宽高缩放
                    if (sBitmapOptionsCache.outWidth != w ||
                            sBitmapOptionsCache.outHeight != h) {
                        Bitmap tmp = Bitmap.createScaledBitmap(b, w, h, true);

                        if (tmp != b) {
                            b.recycle();
                        }
                        b = tmp;
                    }
                }

                return b;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (fd != null) {
                    try {
                        fd.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

        }
        //默认图片
        return BitmapUtil.drawable2bitamp(context.getResources().getDrawable(R.drawable.img_album_background));
    }

    /**
     * 获取AlbumArtPath
     * @param context
     * @param albumid
     * @return
     */
    public static String getAlbumArtPath(Context context, Long albumid) {
        String strAlbums = "content://media/external/audio/albums";
        String[] projection = new String[]{android.provider.MediaStore.Audio.AlbumColumns.ALBUM_ART};
        Cursor cur = context.getContentResolver().query(
                Uri.parse(strAlbums + "/" + albumid),
                projection, null, null, null);
        String strPath = null;
        if (cur.getCount() > 0 && cur.getColumnCount() > 0) {
            cur.moveToNext();
            strPath = cur.getString(0);
        }
        cur.close();
        cur = null;
        return strPath;
    }

    
    
    
    
    /**
     * 获取Cursor中的歌曲数据
     * @param cursor
     * @return
     */
    public static List<AbstractMusic> getMusicList(Cursor cursor) {
        if (cursor == null) {
            return null;
        }
        List<AbstractMusic> musicInfoList = new ArrayList<AbstractMusic>();
        while (cursor.moveToNext()) {
            MusicInfo musicInfo = new MusicInfo();
            musicInfo.setSongId(cursor.getLong(cursor.getColumnIndex("SONG_ID")));
            musicInfo.setAlbumId(cursor.getLong(cursor.getColumnIndex("ALBUM_ID")));
            musicInfo.setArtistId(cursor.getLong(cursor.getColumnIndex("ARTIST_ID")));
            musicInfo.setTitle(cursor.getString(cursor.getColumnIndex("TITLE")));
            musicInfo.setAlbum(cursor.getString(cursor.getColumnIndex("ALBUM")));
            musicInfo.setArtist(cursor.getString(cursor.getColumnIndex("ARTIST")));
            musicInfo.setDuration(cursor.getInt(cursor.getColumnIndex("DURATION")));
            musicInfo.setPath(cursor.getString(cursor.getColumnIndex("PATH")));
            musicInfo.setAddTime(cursor.getLong(cursor.getColumnIndex("ADD_TIME")));
            musicInfo.setFavorite(cursor.getInt(cursor.getColumnIndex("FAVORITE")));
            musicInfoList.add(musicInfo);
        }
        cursor.close();
//        for(MusicInfo m : musicInfoList) {
//        	System.out.println(m.getSongId() + " " + m.getArtist() + " - " + m.getTitle() + " " + m.getDurationStr() + " " + m.getPath());
//        }
        return musicInfoList;
    }

    /**
     * 获取Cursor中的专辑数据
     * @param cursor
     * @return
     */
    public static List<AlbumInfo> getAlbumList(Cursor cursor) {
        if (cursor == null) {
            return null;
        }
        List<AlbumInfo> albumInfoList = new ArrayList<AlbumInfo>();
        while (cursor.moveToNext()) {
            AlbumInfo albumInfo = new AlbumInfo();
            albumInfo.setAlbumId(cursor.getLong(cursor.getColumnIndex("ALBUM_ID")));
            albumInfo.setTitle(cursor.getString(cursor.getColumnIndex("TITLE")));
            albumInfo.setArtist(cursor.getString(cursor.getColumnIndex("ARTIST")));
            albumInfo.setNumSongs(cursor.getInt(cursor.getColumnIndex("NUM_SONGS")));
            albumInfo.setAlbumArt(cursor.getString(cursor.getColumnIndex("ALBUM_ART")));
            albumInfoList.add(albumInfo);
        }
        cursor.close();
        return albumInfoList;
    }

    /**
     * 获取Cursor中的艺术家数据
     * @param cursor
     * @return
     */
    public static List<ArtistInfo> getArtistList(Cursor cursor) {
        if (cursor == null) {
            return null;
        }
        List<ArtistInfo> artistInfoList = new ArrayList<ArtistInfo>();
        while (cursor.moveToNext()) {
            ArtistInfo artistInfo = new ArtistInfo();
            artistInfo.setArtistId(cursor.getLong(cursor.getColumnIndex("ARTIST_ID")));
            artistInfo.setArtist(cursor.getString(cursor.getColumnIndex("ARTIST")));
            artistInfo.setNumSongs(cursor.getInt(cursor.getColumnIndex("NUM_SONGS")));
            artistInfo.setAlbumArt(cursor.getString(cursor.getColumnIndex("ALBUM_ART")));
            artistInfoList.add(artistInfo);
        }
        cursor.close();
        return artistInfoList;
    }
}
